package cn.edu.jxnu.leetcode;

/**
 * @author 梦境迷离
 * @description 深度优先搜索在得到到一个新节点时立马对新节点进行遍历：从节点 0 出发开始遍历，得到到新节点 6 时，立马对新节点 6
 *              进行遍历，得到新节点 4；如此反复以这种方式遍历新节点，直到没有新节点了，此时返回。返回到根节点 0 的情况是，继续对根节点 0
 *              进行遍历，得到新节点 2，然后继续以上步骤。
 * 
 *              从一个节点出发，使用 DFS 对一个图进行遍历时，能够遍历到的节点都是从初始节点可达的，DFS 常用来求解这种 可达性 问题。
 * 
 *              在程序实现 DFS 时需要考虑以下问题：
 * 
 *              栈：用栈来保存当前节点信息，当遍历新节点返回时能够继续遍历当前节点。可以使用递归栈。
 * 
 *              标记：和 BFS 一样同样需要对已经遍历过的节点进行标记。
 * 
 *              输入: [[1,1,0], [1,1,0], [0,0,1]] 输出: 2 说明：已知学生0和学生1互为朋友，他们在一个朋友圈。
 *              第2个学生自己在一个朋友圈。所以返回2。 示例 2:
 * 
 *              输入: [[1,1,0], [1,1,1], [0,1,1]] 输出: 1
 *              说明：已知学生0和学生1互为朋友，学生1和学生2互为朋友，所以学生0和学生2也是朋友，所以他们三个在一个朋友圈，返回1。 2.
 * @time 2018年4月8日
 */
public class Leetcode_695_DFS {

	/**
	 * 
	 * @author 梦境迷离
	 * @description 班上有 N 名学生。其中有些人是朋友，有些则不是。他们的友谊具有是传递性。如果已知 A 是 B 的朋友，B 是 C
	 *              的朋友，那么我们可以认为 A 也是 C 的朋友。所谓的朋友圈，是指所有朋友的集合。
	 * 
	 *              给定一个 N * N 的矩阵 M，表示班级中学生之间的朋友关系。如果M[i][j] = 1，表示已知第 i 个和 j
	 *              个学生互为朋友关系，否则为不知道。你必须输出所有学生中的已知的朋友圈总数。
	 * 
	 *              注意：N 在[1,200]的范围内。 对于所有学生，有M[i][i] = 1。 如果有M[i][j] =
	 *              1，则有M[j][i] = 1。
	 * 
	 * @time 2018年4月8日
	 */
	public int maxAreaOfIsland(int[][] grid) {
		int max = 0;
		for (int i = 0; i < grid.length; i++) {
			for (int j = 0; j < grid[i].length; j++) {
				if (grid[i][j] == 1) {
					max = Math.max(max, dfs(grid, i, j));
				}
			}
		}
		return max;
	}

	private int dfs(int[][] grid, int i, int j) {
		if (i < 0 || i >= grid.length || j < 0 || j >= grid[i].length || grid[i][j] == 0) {
			return 0;
		}
		// 标记
		grid[i][j] = 0;
		return dfs(grid, i + 1, j) + dfs(grid, i - 1, j) + dfs(grid, i, j + 1) + dfs(grid, i, j - 1) + 1;
	}
}
